import paper from 'paper'

const local = {
  path: null,
  show: null,
  segment: null,
  line: null,
  movePoint: null,
  count: 0,
  isDraged: false,
}

const moveOptions = {
  match: (hitResult) => {
    if (hitResult && hitResult.item && hitResult.item.markType === 'linePoint') {
      return true
    }
    return false
  },
  segments: true,
  stroke: true,
  tolerance: 2,
}

const clickOptions = {
  match: (hitResult) => {
    if (hitResult && hitResult.item && hitResult.item.markType === 'line') {
      return true
    }
    return false
  },
  stroke: true,
  tolerance: 2,
}

const linePointNormalSize = 4
const linePointExpandSize = 12
const lineWidth = 2

const onMouseMove = (event) => {
  document.querySelector('body').style.cursor = 'crosshair'
  if (local.path) {
    if (local.path.segments.length > local.count) {
      local.path.segments[local.path.segments.length - 1].remove()
    }
    local.path.add(event.point)
  } else {
    local.segment = null
    local.movePoint = null
    let hitResult = paper.project.hitTest(event.point, moveOptions)
    paper.project.activeLayer.children.forEach((child) => {
      if (child.markType === 'linePoint') {
        child.strokeWidth = linePointNormalSize
      }
    })
    if (hitResult) {
      hitResult.item.strokeWidth = linePointExpandSize
      let p = hitResult.item
      let l = hitResult.item.line
      l.segments.forEach((element) => {
        if (element.point.x == p.segments[0].point.x && element.point.y == p.segments[0].point.y)
          local.segment = element
      })
      local.movePoint = p
    }
  }
}

const onMouseDown = (event) => {
  local.isDraged = false
  if (local.path) {
    // local.path.add(event.point)
    // local.count++
    // const point = new paper.Path()
    // point.add(event.point)
    // point.markType = 'linePoint'
    // point.strokeCap = 'round'
    // point.strokeColor = 'red'
    // point.selectedColor = 'red'
    // point.strokeScaling = false
    // point.strokeWidth = linePointNormalSize
    // point.opacity = 1
    // point.closed = true
    // point.line = local.path
    // local.path.points.push(point)
  } else {
    if (local.segment) {
      if (event.modifiers.alt) {
        // 已有的线删点
        if (local.movePoint && local.movePoint.line.segments.length <= 2) {
          let l = local.movePoint.line
          l.points.forEach((p) => {
            p.remove()
          })
          l.remove()
        } else {
          local.segment.remove()
          local.movePoint.remove()
        }
        return
      }
    }
    if (event.modifiers.alt) {
      // 已有的线插点
      let hitResult = paper.project.hitTest(event.point, clickOptions)
      if (hitResult.type == 'stroke' && hitResult.item.markType === 'line') {
        local.segment = hitResult.item.insert(hitResult.location.index + 1, event.point)
        const point = new paper.Path()
        point.add(event.point)
        point.markType = 'linePoint'
        point.strokeCap = 'round'
        point.strokeColor = 'red'
        point.selectedColor = 'red'
        point.strokeScaling = false
        point.strokeWidth = linePointNormalSize
        point.opacity = 1
        point.closed = true
        point.line = hitResult.item
      }
    } else if (!local.segment) {
      local.path = new paper.Path()
      local.path.markType = 'line'
      local.path.action = 'addNew'
      local.path.strokeColor = 'yellow'
      local.path.strokeWidth = lineWidth
      // local.path.strokeCap = "round";
      // local.path.strokeJoin = "round";
      local.path.strokeScaling = false
      local.path.add(event.point)
      local.count++
      local.path.points = []
      const point = new paper.Path()
      point.add(event.point)
      point.markType = 'linePoint'
      point.strokeCap = 'round'
      point.strokeColor = 'red'
      point.selectedColor = 'red'
      point.strokeScaling = false
      point.strokeWidth = linePointNormalSize
      point.opacity = 1
      point.closed = true
      point.line = local.path
      local.path.points.push(point)
      local.path.toDBObject = function () {
        let labels = {
          a1: this.a1,
          a2: this.a2,
          a3: this.a3,
          a4: this.a4,
          a5: this.a5,
          a6: this.a6,
          a7: this.a7,
          a8: this.a8,
          b1: this.b1,
          b2: this.b2,
          b3: this.b3,
          b4: this.b4,
          b5: this.b5,
          b6: this.b6,
          b7: this.b7,
          b8: this.b8,
        }
        labels = JSON.stringify(labels)
        let x = ''
        let y = ''
        let z = tool.isLine === true ? 'line' : 'poly'
        this.segments.forEach((element) => {
          let tmpPoint = globalToLocal(element.point)
          x += tmpPoint.x.toFixed(2) + ';'
          y += tmpPoint.y.toFixed(2) + ';'
        })
        const ret = {
          mMarkAnnotationId: null,
          mQaResultId: this.mQaResultId,
          name: this.labelName,
          x: x,
          y: y,
          z: z,
          a1: this.a1,
          a2: this.a2,
          a3: this.a3,
          a4: this.a4,
          a5: this.a5,
          a6: this.a6,
          a7: this.a7,
          a8: this.a8,
          b1: this.b1,
          b2: this.b2,
          b3: this.b3,
          b4: this.b4,
          b5: this.b5,
          b6: this.b6,
          b7: this.b7,
          b8: this.b8,
          labels: labels,
          fileType: '2d',
          fileName: this.fileName,
        }
        return ret
      }
      local.path.fileName = paper.project.fileName
      local.path.mQaResultId = paper.project.mQaResultId
    }
  }
}

const onMouseDrag = (event) => {
  if (event.event.buttons == 2) {
    if (paper.project.activeLayer.rasterLayer) {
      paper.project.activeLayer.rasterLayer.position.x += event.delta.x
      paper.project.activeLayer.rasterLayer.position.y += event.delta.y
      paper.project.activeLayer.position.x += event.delta.x
      paper.project.activeLayer.position.y += event.delta.y
      local.isDraged = true
    }
  }

  if (local.segment) {
    local.segment.point.x += event.delta.x
    local.segment.point.y += event.delta.y
    local.movePoint.segments[0].point.x += event.delta.x
    local.movePoint.segments[0].point.y += event.delta.y
  } else if (local.line) {
    local.line.position.x += event.delta.x
    local.line.position.y += event.delta.y
  }
}

const onMouseUp = (event) => {
  if (!local.isDraged) {
    if (event.event.button == 2 && local.path) {
      if (local.path.segments.length > local.count) {
        local.path.segments[local.path.segments.length - 1].remove()
      }
      if (local.path.points && local.path.points.length == 1) {
        local.path.points[0].remove()
      }
      if (tool.newMarkEvent) {
        tool.newMarkEvent(local.path, function (params) {
          if (params.ret !== 'confirm') {
            let line = params.form.instance
            line.points.forEach((point) => {
              point.remove()
            })
            line.remove()
          }
        })
      }
      local.path = null
      local.segment = null
      local.count = 0
    } else if (local.path) {
      local.path.add(event.point)
      local.count++
      const point = new paper.Path()
      point.add(event.point)
      point.markType = 'linePoint'
      point.strokeCap = 'round'
      point.strokeColor = 'red'
      point.selectedColor = 'red'
      point.strokeScaling = false
      point.strokeWidth = linePointNormalSize
      point.opacity = 1
      point.closed = true
      point.line = local.path
      local.path.points.push(point)
    }
  }

  local.isDraged = false
}

const onToggleIn = () => {}
const onToggleOut = () => {
  if (local.show) local.show.remove()
  local.show = null
}

function globalToLocal(point) {
  return paper.project.activeLayer.rasterLayer.globalToLocal(point)
}

export const tool = new paper.Tool()
tool.onMouseDown = onMouseDown
tool.onMouseDrag = onMouseDrag
tool.onMouseUp = onMouseUp
tool.onMouseMove = onMouseMove
tool.onToggleIn = onToggleIn
tool.onToggleOut = onToggleOut
